
package gpinterpreter;
import gpinterpreter.vector.VecInstruction;
import java.util.List;
import primitives.cluster.ClusterHead;


/**
 *
 * @author mat
 */


public abstract class Interpreter<T extends Instruction> {
	protected ClusterHead tree; // we're doing agglomerative clustering so we
	// always have a tree.
	protected int pc = 0;
	protected List<T> program;
	

	
	public Interpreter(List<T> p, ClusterHead c) {
		program = p;
		tree = c;
	}
	
	public abstract void execute(T instruction);

	
	protected void init(){
		//void
	}
    public ClusterHead getTree() {
        return tree;
    }

	/***
	 * Has execution finished?. This will return true if the program counter is past
	 * the final instruction.
	 * @return false if there are more instructions to execute, true otherwise.
	 */
    public boolean isHalted() {
        return pc >= program.size();
    }

    /**
     * Restart execution of the program. Note that this will restart the program
     * on the already-modified tree, keep a reference to the original tree if
     * restarting is necessary.
     *
     *
     */
    public void reset() {
        pc = 0;
    }

    /**
     * Run the program on the tree, returning the modified cluster tree. This
     * program executes step() until isHalted returns true.
     *
     * @return ClusterHead tree representing the clustering produced by the
     *         program
     */
    public ClusterHead run() {
        while (!isHalted()) {
            step();
        }
        return tree;
    }

	
	/***
	 * Sets the ClusterHead to run on. The argument will be modified as described
	 * by the program (list of Instructions) being executed. Assume this tree is
	 * destroyed irreparably by the force of 1000 suns; if you care what was in 
	 * tree before this method is called, pass a copy or save a copy.
	 * @param tree the initial clustering to run the program on.
	 */
    public void setTree(ClusterHead tree) {
        this.tree = tree;
    }

    /**
     * Execute one instruction on the tree.
     */
    public void step() {
        if (isHalted()) {
            return;
        }
        T i = program.get(pc);
        execute(i);
        pc++;
    }
	
	
    
}
